package com.esun.payment_api.service.impl;

import com.esun.common.api.CommonPage;
import com.esun.common.api.CommonResult;
import com.esun.common.api.ResultCode;
import com.esun.common.bean.PageRequest;
import com.esun.common.utils.IpUtils;
import com.esun.common.utils.ServletUtils;
import com.esun.common.utils.StringUtils;
import com.esun.payment_api.bean.UserBean;
import com.esun.payment_api.controller.BaseController;
import com.esun.payment_api.domain.SysLog;
import com.esun.payment_api.domain.SysLogExample;
import com.esun.payment_api.domain.SysLogWithBLOBs;
import com.esun.payment_api.domain.User;
import com.esun.payment_api.mapper.SysLogMapper;
import com.esun.payment_api.service.LogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class LogServiceImpl extends BaseController implements LogService {

    @Autowired
    private SysLogMapper sysLogMapper;

    final Boolean defaultUser = false;

    public User getUser(){
        User user;
        try{
            user = getLoginUser();
            return user;
        } catch (Exception e){
            if(defaultUser){
                user = new User();
                user.setId((short)1);
                return user;
            }else{
                System.out.println("日志模块获取用户失败，参考原因"+e.getMessage());
                return null;
            }
        }
    }

    public CommonResult writeLog(String moduleName, CommonResult commonResult, String logType) {
        try {
            SysLogWithBLOBs sysLog = new SysLogWithBLOBs();
            User user = getUser();
            sysLog.setCreateBy(user.getId());
            sysLog.setCoId(user.getCoId());
//            sysLog.setIpAddr(getIpAddress());
            sysLog.setIpAddr(IpUtils.getIpAddr(ServletUtils.getRequest()));
            sysLog.setModelTitle(moduleName);
            if(commonResult.getCode()== ResultCode.SUCCESS.getCode()){
                sysLog.setLogType(logType);
            }else{
                sysLog.setLogType("错误");
            }
            sysLog.setContent(commonResult.getMessage());
            if(sysLogMapper.insertSelective(sysLog)!=1){
                return CommonResult.success(null, "日志写入成功");
            } else {
                return CommonResult.success(null, "日志写入失败");
            }
        } catch (Exception e) {
            System.out.println("日志写入失败，参考信息： " + e.getMessage());
            return CommonResult.failed("日志写入失败");
        }
    }

    public CommonResult writeCustomLog(String moduleName, String message, String logType) {
        try {
            SysLogWithBLOBs sysLog = new SysLogWithBLOBs();
            User user = getUser();
            sysLog.setCreateBy(user.getId());
            sysLog.setCoId(user.getCoId());
//            sysLog.setIpAddr(getIpAddress());
            sysLog.setIpAddr(IpUtils.getIpAddr(ServletUtils.getRequest()));
            sysLog.setModelTitle(moduleName);
            sysLog.setLogType(logType);
            sysLog.setContent(message);
            if(sysLogMapper.insertSelective(sysLog)!=1){
                return CommonResult.success(null, "日志写入成功");
            } else {
                return CommonResult.success(null, "日志写入失败");
            }
        } catch (Exception e) {
            System.out.println("日志写入失败，参考信息： " + e.getMessage());
            return CommonResult.failed("日志写入失败");
        }
    }

    public CommonResult writeAccessLog(String moduleName, CommonResult commonResult) {
        try {
            String logType = "访问";
            CommonResult commonResultOutput = writeLog(moduleName, commonResult, logType);
            return commonResultOutput;
        } catch (Exception e) {
            System.out.println("日志写入失败，参考信息： " + e.getMessage());
            return CommonResult.failed("日志写入失败");
        }
    }

    public CommonResult writeOperationLog(String moduleName, CommonResult commonResult) {
        try {
            String logType = "操作";
            CommonResult commonResultOutput = writeLog(moduleName, commonResult, logType);
            return commonResultOutput;
        } catch (Exception e) {
            System.out.println("日志写入失败，参考信息： " + e.getMessage());
            return CommonResult.failed("日志写入失败");
        }
    }

    public CommonResult writeOtherLog(String moduleName, CommonResult commonResult, String logType) {
        try {
            CommonResult commonResultOutput = writeLog(moduleName, commonResult, logType);
            return commonResultOutput;
        } catch (Exception e) {
            System.out.println("日志写入失败，参考信息： " + e.getMessage());
            return CommonResult.failed("日志写入失败");
        }
    }

    public CommonResult getLogList(PageRequest pageRequest) {
        try {
            SysLogExample sysLogExample = new SysLogExample();
            SysLogExample.Criteria sysLogExampleCriteria = sysLogExample.createCriteria();
            if(pageRequest.getConditions()!=null && pageRequest.getConditions().get("coId")!=null){
                sysLogExampleCriteria.andCoIdEqualTo(Short.valueOf(pageRequest.getConditions().get("coId")));
            }
            sysLogExample.setOrderByClause("id desc");
            List<SysLog> sysLogList = sysLogMapper.selectByExample(sysLogExample);
            CommonPage sysLogCommonPage = new CommonPage<>();
            sysLogCommonPage.setList(sysLogList);
            CommonResult commonResult = CommonResult.success(sysLogList, "读取系统日志成功");
            return commonResult;
        } catch (Exception e) {
            System.out.println("日志读取失败，参考信息： " + e.getMessage());
            return CommonResult.failed("日志读取失败，参考信息： " + e.getMessage());
        }
    }

    public CommonResult writeLoginLog(UserBean user, CommonResult commonResult) {
        try {
            SysLogWithBLOBs sysLog = new SysLogWithBLOBs();
            if(user!=null){
                sysLog.setCreateBy(user.getId());
                sysLog.setCoId(user.getCoId());
            }

            sysLog.setIpAddr(IpUtils.getIpAddr(ServletUtils.getRequest()));
            sysLog.setModelTitle("登陆模块");
            if(commonResult.getCode()== ResultCode.SUCCESS.getCode()){
                sysLog.setLogType("登陆成功");
            }else{
                sysLog.setLogType("登陆失败");
            }
            sysLog.setContent(commonResult.getMessage());
            if(sysLogMapper.insertSelective(sysLog)!=1){
                return CommonResult.success(null, "日志写入成功");
            } else {
                return CommonResult.success(null, "日志写入失败");
            }
        } catch (Exception e) {
            System.out.println("日志写入失败，参考信息： " + e.getMessage());
            return CommonResult.failed("日志写入失败");
        }
    }

    public CommonResult writeErrorLog(String errorMessage, String moduleName){
        try {
            CommonResult commonResult = CommonResult.failed(errorMessage);
            CommonResult commonResultOutput = writeLog(moduleName, commonResult, "错误");
            return commonResultOutput;
        } catch (Exception e) {
            System.out.println("日志写入失败，参考信息： " + e.getMessage());
            return CommonResult.failed("日志写入失败");
        }
    }

    // 方法1
    private String getNowIP1() throws IOException {
        String ip = null;
        String chinaz = "http://ip.chinaz.com";
        StringBuilder inputLine = new StringBuilder();
        String read = "";
        URL url = null;
        HttpURLConnection urlConnection = null;
        BufferedReader in = null;
        try {
            url = new URL(chinaz);
            urlConnection = (HttpURLConnection) url.openConnection();
            in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "UTF-8"));
            while ((read = in.readLine()) != null) {
                inputLine.append(read + "\r\n");
            }
            Pattern p = Pattern.compile("\\<dd class\\=\"fz24\">(.*?)\\<\\/dd>");
            Matcher m = p.matcher(inputLine.toString());
            if (m.find()) {
                String ipstr = m.group(1);
                ip = ipstr;
            }
        } finally {
            if (in != null) {
                in.close();
            }
        }
        if (StringUtils.isEmpty(ip)) {
            throw new RuntimeException();
        }
        return ip;
    }
    // 方法2 -- 太卡了不用
    private String getNowIP2() throws IOException {
        String ip = null;
        BufferedReader br = null;
        try {
            URL url = new URL("https://v6r.ipip.net/?format=callback");
            br = new BufferedReader(new InputStreamReader(url.openStream()));
            String s = "";
            StringBuffer sb = new StringBuffer("");
            String webContent = "";
            while ((s = br.readLine()) != null) {
                sb.append(s + "\r\n");
            }
            webContent = sb.toString();
            int start = webContent.indexOf("(") + 2;
            int end = webContent.indexOf(")") - 1;
            webContent = webContent.substring(start, end);
            ip = webContent;
        } finally {
            if (br != null)
                br.close();
        }
        if (StringUtils.isEmpty(ip)) {
            throw new RuntimeException();
        }
        return ip;
    }
    // 方法3
    private String getNowIP3() throws IOException {
        String ip = null;
        String objWebURL = "https://ip.900cha.com/";
        BufferedReader br = null;
        try {
            URL url = new URL(objWebURL);
            br = new BufferedReader(new InputStreamReader(url.openStream()));
            String s = "";
            String webContent = "";
            while ((s = br.readLine()) != null) {
                if (s.indexOf("我的IP:") != -1) {
                    ip = s.substring(s.indexOf(":") + 1);
                    break;
                }
            }
        } finally {
            if (br != null)
                br.close();
        }
        if (StringUtils.isEmpty(ip)) {
            throw new RuntimeException();
        }
        return ip;
    }
    // 方法4-可行
    private String getNowIP4() throws IOException {
        String ip = null;
        String objWebURL = "https://bajiu.cn/ip/";
        BufferedReader br = null;
        try {
            URL url = new URL(objWebURL);
            br = new BufferedReader(new InputStreamReader(url.openStream()));
            String s = "";
            String webContent = "";
            while ((s = br.readLine()) != null) {
                if (s.indexOf("互联网IP") != -1) {
                    ip = s.substring(s.indexOf("'") + 1, s.lastIndexOf("'"));
                    break;
                }
            }
        } finally {
            if (br != null)
                br.close();
        }
        if (StringUtils.isEmpty(ip)) {
            throw new RuntimeException();
        }
        return ip;
    }

    // 获取用户的公网IP地址。摘自https://www.jianshu.com/p/d985711629da
    //现在已经不用了
    public String getIpAddress() {
        String ip = null;
        // 第一种方式
        try {
            ip = this.getNowIP1();
            ip.trim();
        } catch (Exception e) {
            System.out.println("getPublicIP - getNowIP1 failed ~ ");
        }
        if (!StringUtils.isEmpty(ip))
            return ip;
//        // 第二种方式
//        try {
//            ip = this.getNowIP2();
//            ip.trim();
//        } catch (Exception e) {
//            System.out.println("getPublicIP - getNowIP2 failed ~ ");
//        }
//        if (!StringUtils.isEmpty(ip))
//            return ip;
        // 第三种方式
        try {
            ip = this.getNowIP3();
            ip.trim();
        } catch (Exception e) {
            System.out.println("getPublicIP - getNowIP3 failed ~ ");
        }
        if (!StringUtils.isEmpty(ip))
            return ip;
        // 第四种方式
        try {
            ip = this.getNowIP4();
            ip.trim();
        } catch (Exception e) {
            System.out.println("getPublicIP - getNowIP4 failed ~ ");
        }
        if (!StringUtils.isEmpty(ip))
            return ip;
        return ip;
    }

}
